package com.suhe.ozon.service;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.suhe.ozon.dao.OrderDao;
import com.suhe.ozon.entity.dto.OrderDTO;
import com.suhe.ozon.entity.po.ClientPO;
import com.suhe.ozon.entity.po.OrderPO;
import com.suhe.ozon.entity.po.OrderProductPO;
import lombok.RequiredArgsConstructor;
import org.springframework.mail.javamail.JavaMailSender;
import org.springframework.mail.javamail.MimeMessageHelper;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.mail.MessagingException;
import javax.mail.internet.MimeMessage;
import java.math.BigDecimal;
import java.time.format.DateTimeFormatter;
import java.util.List;

/**
 * <p>
 *     订单Service
 * </p>
 *
 * @author liuning
 * @date 14:31 2024/1/19
 */
@Service
@RequiredArgsConstructor
public class OrderService extends ServiceImpl<OrderDao, OrderPO> {

    private final OrderProductService orderProductService;

    private final JavaMailSender javaMailSender;

    /**
     * 新增或更新
     *
     * @param orderDTO
     */
    @Transactional
    public void saveOrModify(OrderDTO orderDTO, ClientPO clientPO) throws MessagingException {
        insertOrModify(orderDTO, clientPO);
        orderProductService.saveOrModify(orderDTO.getOrderNo(), orderDTO.getProducts());
        // 更新订单中的数据
        final List<OrderProductPO> orderProducts = orderProductService.listByOrderNo(orderDTO.getOrderNo());
        final int productQuantity = orderProducts.stream().mapToInt(OrderProductPO::getProductQuantity).sum();
        orderDTO.setProductQuantity(productQuantity);
        final BigDecimal orderPrice = orderProducts.stream().map(p -> p.getProductPrice().multiply(new BigDecimal(p.getProductQuantity()))).reduce(BigDecimal::add).orElse(BigDecimal.ZERO);
        orderDTO.setOrderPrice(orderPrice);
        this.updateById(orderDTO);
    }

    /**
     * 新增或更新
     *
     * @param orderDTO
     * @param clientPO
     */
    @Transactional
    public void insertOrModify(OrderDTO orderDTO, ClientPO clientPO) throws MessagingException {
        final OrderPO target = getByOrderNo(orderDTO.getOrderNo());
        if (target == null) {
            // 邮件通知
            final MimeMessage message = javaMailSender.createMimeMessage();
            final MimeMessageHelper messageHelper = new MimeMessageHelper(message, true);
            messageHelper.setFrom("17621413065@163.com");
            messageHelper.setTo(clientPO.getEmail());
            messageHelper.setSubject("您收到一笔订单！");
            messageHelper.setText(createEmailContent(orderDTO));
//            javaMailSender.send(message);
            this.save(orderDTO);
        } else {
            target.cover(orderDTO);
            this.updateById(target);
        }
    }

    /**
     * 根据订单编号获取订单信息
     *
     * @param orderNo
     * @return
     */
    public OrderPO getByOrderNo(String orderNo) {
        return getBaseMapper().getByOrderNo(orderNo);
    }

    /**
     * 根据客户端id获取最新一笔订单数据
     *
     * @return
     */
    public OrderPO getLastOrder(String clientId) {
        return getBaseMapper().selectOne(Wrappers.lambdaQuery(OrderPO.class).eq(OrderPO::getClientId, clientId).orderByDesc(OrderPO::getOrderTime).last(" limit 1"));
    }

    /**
     * 根据物流跟踪号获取订单信息
     *
     * @param trackingNumber
     * @return
     */
    public OrderPO getByTrackingNumber(String trackingNumber) {
        return this.getOne(Wrappers.lambdaQuery(OrderPO.class).eq(OrderPO::getTrackingNumber, trackingNumber));
    }

    /**
     * 生成邮件文本
     *
     * @param orderDTO
     * @return
     */
    private String createEmailContent(OrderDTO orderDTO) {
        final StringBuffer orderStr = new StringBuffer(StrUtil.format("订单号: {}, 订单金额: {}, 下单时间: {}\r\n", orderDTO.getOrderNo(), orderDTO.getOrderPrice(), orderDTO.getOrderTime().format(DateTimeFormatter.ofPattern(DatePattern.CHINESE_DATE_TIME_PATTERN))));
        orderDTO.getProducts().forEach(product -> {
            String line = "---------------- 商品信息 ----------------\r\n";
            final String productText = StrUtil.format(" 商品名称: {}, 商品价格: {}, 商品sku: {}, 商品数量: {}\r\n", product.getProductName(), product.getProductPrice(), product.getProductSku(), product.getProductQuantity());
            orderStr.append(line).append(productText);
        });
        return orderStr.toString();
    }
}
